package filters;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.*;
import java.util.*;

import javax.servlet.*;
import javax.servlet.http.*;

import net.begincode.servlet.common.BaseServlet;

import org.apache.commons.lang.StringUtils;

import utils.BQStringUtil;

public class URLMappingFilter extends BaseServlet implements Filter {
	private ServletContext context;
	private List<String> ignoreURIs = new ArrayList<String>();
	private List<String> ignoreExts = new ArrayList<String>();
	private List<String> packages = new ArrayList<String>();
	public URLMappingFilter() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void destroy() {
		

	}
	/**
	 * 接收所有url路径，并通过路径反射调用相关的类文件的某个方法，
	 * 如  order/selOrder  通过该过滤器 反射调用OrderServlet的selOrder 的方法
	 * */
	@Override
	public void doFilter(ServletRequest req, ServletResponse rep,
			FilterChain chain) throws IOException, ServletException {
		 
		//获取url并拆分各种变量
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) rep;
		String path = request.getContextPath();
		String basePath = request.getScheme() + "://" + request.getServerName()
				+ ":" + request.getServerPort() + path + "/";
		String remoteAddress = request.getRemoteAddr();
		String servletPath = request.getServletPath();
		String remoteUser = request.getRemoteUser();
		String requestURI = request.getRequestURI();

		Class<?> demo = null;
		
//		System.out.println("YANG" + requestUri.substring(startIndex, endIndex));
//		判断请求路径,并过滤
//		System.out.println("servletPath:"+servletPath);
//		System.out.println("忽略"+ignoreURIs);
		servletPath = servletPath.replaceAll("/begincode", "");
		if(servletPath.equals("/index.jsp")){
			
			//首页跳转到初始化方法
			demo = loadAction("HomeServlet");
			Method method;
			try {
				method = demo.getMethod("initBeginCode", HttpServletRequest.class , HttpServletResponse.class  );
				method.invoke(demo.newInstance(),req,rep);
				
			}  catch (Exception e) {
				e.printStackTrace();
				request.getRequestDispatcher("/WEB-INF/404.jsp").forward(request, response);
			}
			
		}else{
			
			//判断忽略后缀和文件类型，如果符合忽略条件，则忽略不进行跳转
			if(BQStringUtil.getFirstUri(servletPath).equals("") || ignoreURIs.contains(BQStringUtil.getFirstUri(servletPath)) || ignoreExts.contains(BQStringUtil.getExt(servletPath))){
				request.getRequestDispatcher(servletPath).forward(request, response);
			}else{
				
				//判断路径并用/拆分路径，获得需要调用的文件及方法名称
				String[] paths ;
				if(servletPath.startsWith("/")){
					paths = servletPath.substring(1).split("/");
				}else{
					paths = servletPath.split("/");
				}
				if(paths.length == 2){
					if(paths[1].contains("?")){
						paths[1] = paths[1].substring(0, paths[1].indexOf("?"));
					}
				}
				if(paths.length == 3 && servletPath.endsWith(".html")){
					//判断url结尾，如果是html结尾则需要获取参数
					req.setAttribute("id", paths[2].substring(0,paths[2].length()-5));
				}
				try {
					demo = loadAction(this.upperFirstChar(paths[0])+"Servlet");
					if((paths[1].startsWith("upd") || paths[1].startsWith("add") || paths[1].startsWith("save")) && !paths[1].equals("addUser")){
						//判断方法名如果以add开头，则判断是否登录如果没登陆返回登录界面
						if(!this.checkUser(request, response)){
							request.setAttribute("msg", "您还没有登录");
							request.getRequestDispatcher("/WEB-INF/page/login.jsp").forward(request, response);
						}else{
							Method	method = demo.getMethod(paths[1], HttpServletRequest.class , HttpServletResponse.class  );
							method.invoke(demo.newInstance(),req,response);
						}
					}else{
						Method	method = demo.getMethod(paths[1], HttpServletRequest.class , HttpServletResponse.class  );
						method.invoke(demo.newInstance(),req,response);
					}
				} catch (Exception e) {
					e.printStackTrace();
					request.getRequestDispatcher("/WEB-INF/404.jsp").forward(request, response);
				} finally{
//					 chain.doFilter(request, response); 
				}
				
			}
		}
	}

	@Override
	public void init(FilterConfig cfg) throws ServletException {
		
		this.context = cfg.getServletContext();
		String domain = cfg.getInitParameter("domain");
		
		
		 //某些URL前缀不予处理（例如 /img/***）
        String ignores = cfg.getInitParameter("ignore");
        if(ignores != null)
        for(String ig : StringUtils.split(ignores, ','))
            ignoreURIs.add(ig.trim());
         
        //某些URL扩展名不予处理（例如 *.jpg）
        ignores = cfg.getInitParameter("ignoreExts");
        if(ignores != null)
        for(String ig : StringUtils.split(ignores, ','))
            ignoreExts.add('.'+ig.trim());
        //某些URL扩展名不予处理（例如 *.jpg）
        String packTmps = cfg.getInitParameter("package");
        if(packTmps != null)
        for(String pcg : StringUtils.split(packTmps, ',')){
        	packages.add(pcg.trim());
        }
        

        
        
        
	}
	//首字母大写
	public String upperFirstChar(String src) {
		return src.substring(0, 1).toUpperCase().concat(src.substring(1));
	}
	private Class loadAction(String className) {
		    {
		    	Class action = null;
		            for(String pkg : this.packages){
		                String cls = pkg + '.' + className;
		                action = loadFullAction(cls);
		                if(action != null)
		                    break;
		            }
		            return action ;
		    }
	}
	 private Class loadFullAction(String cls) 
		    {
		 	Class action = null;
		        try {                      
		        	 action = Class.forName(cls);
		        } catch (ClassNotFoundException excp) {}
		        return action;
		    }

}
